﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using AForge.Imaging.Filters;
using BrainTechLLC;
using BrainTechLLC.FilterExtensions;
using BrainTechLLC.ImageOperators;

namespace ImageAppViewModels
{
    public class FilterCollectionViewModel : ObservableCollection<FilterViewModel>
    {
        public event EventHandler<NotifyCollectionChangedEventArgs> GenerationChanged;
        public event EventHandler WantFilterThumbnailsChanged;
        public event EventHandler WantHighQualityThumbsChanged;

        public MoveFilter MoveFilterCommand = new MoveFilter();
        
        protected FilterCollection _collection;

        public FilterCollection Collection
        {
            get { return _collection; }
        }

        public string CollectionName
        {
            get { return _collection.CollectionName; }
            set { _collection.CollectionName = value; }
        }

        public void SetCurrentGeneration(int newGeneration, NotifyCollectionChangedEventArgs e)
        {
            if (_collection.CurrentGeneration != newGeneration)
            {
                _collection.SetCurrentGeneration(newGeneration, e);
                OnPropertyChanged(new PropertyChangedEventArgs("CurrentGeneration"));
            }
        }

        public int CurrentGeneration
        {
            get { return _collection.CurrentGeneration; }
        }

        public bool WantFilterThumbs
        {
            get { return Settings.Values.WantFilterThumbnails; }
            set
            {
                if (Settings.Values.WantFilterThumbnails != value)
                {
                    OnWantFilterThumbnailsChanged(value);
                    OnPropertyChanged(new PropertyChangedEventArgs("WantFilterThumbs"));
                }
            }
        }

        public bool HighQualityThumbs
        {
            get { return Settings.Values.HighQualityThumbs; }
            set
            {
                if (Settings.Values.HighQualityThumbs != value)
                {
                    OnWantHighQualityThumbsChanged(value);
                    OnPropertyChanged(new PropertyChangedEventArgs("HighQualityThumbs"));
                }
            }
        }

        public void OnWantFilterThumbnailsChanged(bool wantFilterThumbs)
        {
            if (Settings.Values.WantFilterThumbnails != wantFilterThumbs)
            {
                Settings.Values.WantFilterThumbnails = wantFilterThumbs;

                if (WantFilterThumbnailsChanged != null)
                    WantFilterThumbnailsChanged(this, EventArgs.Empty);
            }
        }

        public void OnWantHighQualityThumbsChanged(bool wantHQ)
        {
            if (Settings.Values.HighQualityThumbs != wantHQ)
            {
                Settings.Values.HighQualityThumbs = wantHQ;

                if (WantHighQualityThumbsChanged != null)
                    WantHighQualityThumbsChanged(this, EventArgs.Empty);
            }
        }

        public string ActiveOrDisabled
        {
            get { return Active ? "Filters are being Applied" : "Not Applying Filters"; }
        }

        public bool Active
        {
            get { return _collection.Active; }
            set
            {
                if (_collection.Active != value)
                {
                    _collection.Active = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("Active"));
                    OnPropertyChanged(new PropertyChangedEventArgs("ActiveOrDisabled"));
                }
            }
        }

        public FilterCollectionViewModel(FilterCollection collection)
        {
            _collection = collection;
            _collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_collection_CollectionChanged);
            _collection.GenerationChanged += new EventHandler<NotifyCollectionChangedEventArgs>(_collection_GenerationChanged);

            foreach (var item in collection)
            {
                SingleFilter sf = item as SingleFilter;
                if (sf != null)
                {
                    this.Add(new FilterViewModel(sf));
                }
                else
                {
                    Console.WriteLine("TODO");
                }
            }
        }

        void _collection_GenerationChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (GenerationChanged != null)
                GenerationChanged(this, e);
        }

        void _collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            // GotoNextGeneration();
            // HEREHERE
        }

        public int FindIndex(FilterViewModel model)
        {
            for (int n = 0; n < Count; n++)
            {
                if (this[n] == model)
                    return n;
            }
            return -1;
        }

        public void MoveItemLeft(FilterViewModel vm)
        {
            int index = FindIndex(vm);

            if (index <= 0)
                return;

            MoveItemFromTo(index, index - 1);
        }

        public void MoveItemLeftAll(FilterViewModel vm)
        {
            int index = FindIndex(vm);

            if (index <= 0)
                return;

            MoveItemFromTo(index, 0);
        }

        public void MoveItemRightAll(FilterViewModel vm)
        {
            int index = FindIndex(vm);

            if (index < 0 || index >= Count - 1)
                return;

            MoveItemFromTo(index, Count - 1);
        }

        public void MoveItemRight(FilterViewModel vm)
        {
            int index = FindIndex(vm);

            if (index < 0 || index >= Count - 1)
                return;

            MoveItemFromTo(index, index + 1);
        }

        public void MoveItemFromTo(int oldPosition, int newPosition)
        {
            _collection.Move(oldPosition, newPosition);
            Move(oldPosition, newPosition);
        }

        public void Save(string path)
        {
            _collection.Save(path);
        }

        public void AddFilter(ISingleFilter filter)
        {
            _collection.AddFilter(filter);
            this.Add(new FilterViewModel(filter));
        }

        public void InsertFilter(ISingleFilter filter, int location)
        {
            _collection.InsertFilter(filter, location);
            this.Insert(location, new FilterViewModel(filter));
        }

        public void AddFilter(string filterType)
        {
            Type t = AllFilters.FindFilter(filterType);

            if (t != null)
            {
                AddFilter(t);
            }
        }

        public void RemoveFilters(IEnumerable<FilterViewModel> filters)
        {
            foreach (var filter in filters)
            {
                RemoveFilter(filter);
            }
        }

        public void RemoveFilter(FilterViewModel filter)
        {
            _collection.RemoveFilter(filter.Filter);
            this.Remove(filter);
        }

        public void ClearAllFilters()
        {
            _collection.ClearAllFilters();
            Clear();
        }

        protected void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        public void AddFilter(Type type)
        {
            var filter = type.CreateFilter();

            if (filter != null)
            {
                AddFilter(new SingleFilter(filter));
            }
        }

        public void InsertFilter(Type type, int location)
        {
            var filter = type.CreateFilter();

            if (filter != null)
            {
                InsertFilter(new SingleFilter(filter), location);
            }
        }
    }
}
